home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / misc / emu / atari800_tr.lzh / sio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-27  |  17.6 KB  |  763 lines

  1. /*
  2.  *
  3.  * All Input is assumed to be going to RAM (no longer, ROM works, too.)
  4.  * All Output is assumed to be coming from either RAM or ROM
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #ifdef VMS
  13. #include <unixio.h>
  14. #include <file.h>
  15. #else
  16. #include <fcntl.h>
  17. #ifndef AMIGA
  18. #include <unistd.h>
  19. #endif
  20. #endif
  21.  
  22. #ifdef DJGPP
  23. #include "djgpp.h"
  24. #endif
  25.  
  26. static char *rcsid = "$Id: sio.c,v 1.8 1997/09/30 thor,david Exp $";
  27.  
  28. #define FALSE   0
  29. #define TRUE    1
  30.  
  31. #include "atari.h"
  32. #include "cpu.h"
  33. #include "sio.h"
  34. #include "pokey11.h"
  35. #include "mem.h"
  36.  
  37. #define    MAGIC1    0x96
  38. #define    MAGIC2    0x02
  39.  
  40. struct ATR_Header
  41. {
  42.   unsigned char    magic1;
  43.   unsigned char    magic2;
  44.   unsigned char    seccountlo;
  45.   unsigned char    seccounthi;
  46.   unsigned char    secsizelo;
  47.   unsigned char    secsizehi;
  48.   unsigned char    hiseccountlo;
  49.   unsigned char    hiseccounthi;
  50.   unsigned char    gash[8];
  51. };
  52.  
  53. typedef enum Format { XFD, ATR } Format;
  54.  
  55. static Format    format[MAX_DRIVES];
  56. static int    disk[MAX_DRIVES] = { -1, -1, -1, -1, -1, -1, -1, -1 };
  57. static int    sectorcount[MAX_DRIVES];
  58. static int    sectorsize[MAX_DRIVES];
  59.  
  60. static enum DriveStatus
  61. {
  62.   Off,
  63.   NoDisk,
  64.   ReadOnly,
  65.   ReadWrite
  66. } drive_status[MAX_DRIVES];
  67.  
  68. char sio_filename[MAX_DRIVES][FILENAME_LEN];
  69.  
  70. /* Serial I/O emulation support */
  71. UBYTE CommandFrame[6];
  72. int CommandIndex=0;
  73. UBYTE DataBuffer[256+3];
  74. char sio_status[256];
  75. int DataIndex=0;
  76. int TransferStatus=0;
  77. int ExpectedBytes=0;
  78.  
  79.  
  80. void SIO_Initialise (int *argc, char *argv[])
  81. {
  82.   int i;
  83.  
  84.   for (i=0;i<MAX_DRIVES;i++)
  85.     strcpy (sio_filename[i], "Empty");
  86.  
  87.   TransferStatus = SIO_NoFrame;
  88. }
  89.  
  90. int SIO_Mount (int diskno, char *filename)
  91. {
  92.   struct ATR_Header    header;
  93.  
  94.   int    fd;
  95.  
  96.   drive_status[diskno-1] = ReadWrite;
  97.   strcpy (sio_filename[diskno-1], "Empty");
  98.  
  99.   fd = open (filename, O_RDWR, 0777);
  100.   if (fd == -1)
  101.     {
  102.       fd = open (filename, O_RDONLY, 0777);
  103.       drive_status[diskno-1] = ReadOnly;
  104.     }
  105.  
  106.   if (fd)
  107.     {
  108.       int    status;
  109.  
  110.       status = read (fd, &header, sizeof(struct ATR_Header));
  111.       if (status == -1)
  112.     {
  113.       close (fd);
  114.       disk[diskno-1] = -1;
  115.       return FALSE;
  116.     }
  117.  
  118.       strcpy (sio_filename[diskno-1], filename);
  119.  
  120.       if ((header.magic1 == MAGIC1) && (header.magic2 == MAGIC2))
  121.     {
  122.       sectorcount[diskno-1] = header.hiseccounthi << 24 |
  123.         header.hiseccountlo << 16 |
  124.           header.seccounthi << 8 |
  125.         header.seccountlo;
  126.  
  127.       sectorsize[diskno-1] = header.secsizehi << 8 |
  128.         header.secsizelo;
  129.  
  130.       sectorcount[diskno-1] /= 8;
  131.       if (sectorsize[diskno-1] == 256)
  132.         {
  133.           sectorcount[diskno-1] += 3; /* Compensate for first 3 sectors */
  134.           sectorcount[diskno-1] /= 2;
  135.         }
  136.  
  137. #ifdef DEBUG
  138.       printf ("ATR: sectorcount = %d, sectorsize = %d\n",
  139.           sectorcount[diskno-1],
  140.           sectorsize[diskno-1]);
  141. #endif
  142.  
  143.       format[diskno-1] = ATR;
  144.     }
  145.       else
  146.     {
  147.       format[diskno-1] = XFD;
  148.       sectorcount[diskno-1]=lseek(fd,0,SEEK_END)/128;
  149.       lseek(fd,0,SEEK_SET);
  150.       sectorsize[diskno-1]=128;
  151.     }
  152.     }
  153.   else
  154.     {
  155.       drive_status[diskno-1] = NoDisk;
  156.     }
  157.  
  158.   disk[diskno-1] = fd;
  159.  
  160.   return (disk[diskno-1] != -1) ? TRUE : FALSE;
  161. }
  162.  
  163. void SIO_Dismount (int diskno)
  164. {
  165.   if (disk[diskno-1] != -1)
  166.     {
  167.       close (disk[diskno-1]);
  168.       disk[diskno-1] = -1;
  169.       drive_status[diskno-1] = NoDisk;
  170.       strcpy (sio_filename[diskno-1], "Empty");
  171.     }
  172. }
  173.  
  174. void SIO_DisableDrive (int diskno)
  175. {
  176.   drive_status[diskno-1] = Off;
  177.   strcpy (sio_filename[diskno-1], "Off");
  178. }
  179.  
  180. void SizeOfSector(UBYTE unit,int sector,int *sz,ULONG *ofs)
  181. {
  182. int size=128;
  183. ULONG offset=0;
  184.  
  185.     switch (format[unit]) {
  186.     case XFD :
  187.       offset = (sector-1)*128;
  188.       break;
  189.     case ATR :
  190.       if (sector < 4) {
  191.     offset = (sector-1) * 128 + 16;
  192.       } else {
  193.     offset = (sector - 1) * sectorsize[unit] + 16;
  194.     size = sectorsize[unit];
  195.       }
  196. /*
  197.     offset = 3*128 + (sector-4) * sectorsize[unit] + 16;
  198. */
  199.       break;
  200.     default :
  201.       printf ("Fatal Error in atari_sio.c\n");
  202.       Atari800_Exit (FALSE, 1);
  203.     }
  204.  
  205.     if (sz)
  206.       *sz = size;
  207.  
  208.     if (ofs)
  209.       *ofs = offset;
  210. }
  211.  
  212. int SeekSector(int unit,int sector)
  213. {
  214. ULONG offset;
  215. int size;
  216.  
  217.     sprintf (sio_status, "%d: %d", unit+1, sector);
  218.     SizeOfSector(unit,sector,&size,&offset); 
  219.     /* printf("Sector %x,Offset: %x\n",sector,offset); */
  220.     lseek(disk[unit], offset, SEEK_SET);
  221.  
  222.     return size;
  223. }
  224.  
  225.  
  226. /* Unit counts from zero up */
  227. int ReadSector(int unit,int sector,UBYTE *buffer)
  228. {
  229. int size;
  230.  
  231.     if (drive_status[unit] != Off) {
  232.       if (disk[unit] != -1) {
  233.     if (sector<=sectorcount[unit]) {
  234.       size = SeekSector (unit, sector);
  235.       read (disk[unit], buffer, size);
  236.       return 'C';
  237.     } else return 'E';
  238.       } else return 'N';
  239.     } else return 0;
  240. }
  241.  
  242. int WriteSector(int unit,int sector,UBYTE *buffer)
  243. {
  244. int size;
  245.  
  246.     if (drive_status[unit] != Off) {
  247.       if (disk[unit] != -1) {
  248.     if (drive_status[unit] == ReadWrite) {
  249.       if (sector<=sectorcount[unit]) {
  250.         size = SeekSector (unit, sector);
  251.         write (disk[unit], buffer, size);
  252.         return 'C';
  253.       } else return 'E';
  254.     } else return 'E';
  255.       } else return 'N';
  256.     } else return 0;
  257. }
  258.  
  259. int FormatSingle(int unit,UBYTE *buffer)
  260. {
  261. int i;
  262.  
  263.   if (drive_status[unit] != Off) {
  264.     if (disk[unit] != -1) {
  265.       if (drive_status[unit] == ReadWrite) {
  266.     sectorcount[unit] = 720;
  267.     sectorsize[unit] = 128;
  268.     format[unit] = XFD;
  269.     SeekSector(unit,1);
  270.     memset(buffer,0,128);
  271.     for(i=1;i<=720;i++)
  272.       write (disk[unit],buffer,128);
  273.     memset(buffer,0xff,128);
  274.     return 'C';
  275.       } else return 'E';
  276.     } else return 'N';
  277.   } else return 0;
  278. }
  279.  
  280. int FormatEnhanced(int unit,UBYTE *buffer)
  281. {
  282. int i;
  283.  
  284.   if (drive_status[unit] != Off) {
  285.     if (disk[unit] != -1) {
  286.       if (drive_status[unit] == ReadWrite) {
  287.     sectorcount[unit] = 1040;
  288.     sectorsize[unit] = 128;
  289.     format[unit] = XFD;
  290.     SeekSector(unit,1);
  291.     memset(buffer,0,128);
  292.     for(i=1;i<=1040;i++)
  293.       write (disk[unit],buffer,128);
  294.     memset(buffer,0xff,128);
  295.     return 'C';
  296.       } else return 'E';
  297.     } else return 'N';
  298.   } else return 0;
  299. }
  300.  
  301. int WriteStatusBlock(int unit,UBYTE *buffer)
  302. {
  303.  
  304.   if (drive_status[unit] != Off) {
  305.     /* We only care about the density right here. Setting everything else
  306.        right here seems to be non-sense */
  307.     if (format[unit] == ATR) { 
  308.       if (buffer[5]==8) {
  309.     sectorsize[unit] = 256;
  310.       } else {
  311.     sectorsize[unit] = 128;
  312.       }
  313.       sectorcount[unit] = 720;
  314.       return 'C';
  315.     } else return 'E';
  316.   } else return 0;
  317. }
  318.  
  319. int ReadStatusBlock(int unit,UBYTE *buffer)
  320. {
  321. int size;
  322.  
  323.   if (drive_status[unit] != Off) {
  324.     SizeOfSector(unit,0x168,&size,NULL);
  325.     buffer[0] = 40;     /* # of tracks */
  326.     buffer[1] = 1;      /* step rate. No idea what this means */
  327.     buffer[2] = 0;      /* sectors per track. HI byte */
  328.     buffer[3] = 18;     /* sectors per track. LO byte */
  329.     buffer[4] = 1;      /* # of heads */
  330.     if (size==128) {
  331.       buffer[5] = 4;    /* density */
  332.       buffer[6] = 0;    /* HI bytes per sector */
  333.       buffer[7] = 128;  /* LO bytes per sector */
  334.     } else {
  335.       buffer[5] = 8;    /* double density */
  336.       buffer[6] = 1;    /* HI bytes per sector */
  337.       buffer[7] = 0;    /* LO bytes per sector */
  338.     }
  339.     buffer[8] = 1;    /* drive is online */
  340.     buffer[9] = 192;  /* transfer speed. Whatever this means */
  341.     return 'C';
  342.   } else return 0;
  343. }
  344.     
  345. /*
  346.    Status Request from Atari 400/800 Technical Reference Notes
  347.  
  348.    DVSTAT + 0    Command Status
  349.    DVSTAT + 1    Hardware Status
  350.    DVSTAT + 2    Timeout
  351.    DVSTAT + 3    Unused
  352.  
  353.    Command Status Bits
  354.  
  355.    Bit 0 = 1 indicates an invalid command frame was received
  356.    Bit 1 = 1 indicates an invalid data frame was received
  357.    Bit 2 = 1 indicates that a PUT operation was unsuccessful
  358.    Bit 3 = 1 indicates that the diskete is write protected
  359.    Bit 4 = 1 indicates active/standby
  360.    
  361.    plus
  362.  
  363.    Bit 5 = 1 indicates double density
  364.    Bit 7 = 1 indicates duel density disk (1050 format)
  365. */
  366. int DriveStatus(int unit,UBYTE *buffer)
  367. {
  368.     if (drive_status[unit] != Off) {
  369.       if (drive_status[unit] == ReadWrite) {
  370.     buffer[0] = (sectorsize[unit] == 256)?(32+16):(16);
  371.     buffer[1] = (disk[unit] != -1)?(128):(0);
  372.       } else {
  373.     buffer[0] = (sectorsize[unit] == 256)?(32):(0);
  374.     buffer[1] = (disk[unit] != -1)?(192):(64);
  375.       }        
  376.       if (sectorcount[unit]==1040) buffer[0] |= 128;
  377.       buffer[2] = 1;
  378.       buffer[3] = 0;
  379.       return 'C';
  380.     } else return 0;
  381. }
  382.  
  383.  
  384. void SIO (void)
  385. {
  386. int sector = DPeek(0x30a);
  387. UBYTE unit = Peek(0x301) - 1;
  388. UBYTE result=0x00;
  389. ATPtr data = DPeek(0x304);
  390. int length = DPeek(0x308);
  391. int realsize;
  392. int cmd = Peek(0x302);
  393.  
  394. #ifdef MOTIF
  395.     Atari_Set_LED(1);
  396. #endif
  397.  
  398. /*
  399.     printf("SIO: Unit %x,Sector %x,Data %x,Length %x,CMD %x\n",unit,sector,data,length,cmd);
  400. */
  401.  
  402.     if (Peek(0x300) == 0x31) switch (cmd) {
  403.     case 0x4e :  /* Read Status Block */
  404.       if (12 == length) {
  405.     result = ReadStatusBlock(unit,DataBuffer);
  406.     if (result == 'C') 
  407.       CopyToMem(DataBuffer,data,12);
  408.       } else result = 'E';
  409.       break;
  410.     case 0x4f :  /* Write Status Block */
  411.       if (12 == length) {
  412.     CopyFromMem(data,DataBuffer,12);
  413.     result = WriteStatusBlock(unit,DataBuffer);
  414.       } else result = 'E';
  415.       break;
  416.     case 0x50 :  /* Write */
  417.     case 0x57 :
  418.       SizeOfSector(unit,sector,&realsize,NULL);
  419.       if (realsize == length) {
  420.     CopyFromMem(data,DataBuffer,realsize);
  421.     result = WriteSector(unit,sector,DataBuffer);
  422.       } else result = 'E';
  423.       break;
  424.     case 0x52:   /* Read */
  425.       SizeOfSector(unit,sector,&realsize,NULL);
  426.       if (realsize == length) {
  427.     result = ReadSector(unit,sector,DataBuffer);
  428.     if (result == 'C') 
  429.       CopyToMem(DataBuffer,data,realsize);
  430.       }
  431.       else result = 'E';
  432.       break;
  433.     case 0x53:  /* Status */
  434.       if (4 == length) {
  435.     result = DriveStatus(unit,DataBuffer);
  436.     CopyToMem(DataBuffer,data,4);
  437.       } else result = 'E';
  438.       break;
  439.     case 0x21 : /* Single Density Format */
  440.       if (length == 128) {
  441.     result = FormatSingle(unit,DataBuffer);
  442.     if (result == 'C')
  443.       CopyToMem(DataBuffer,data,realsize);
  444.       } else result = 'E';
  445.       break;
  446.     case 0x22 : /* Enhanced Density Format */
  447.       if (length == 128) {
  448.     result = FormatEnhanced(unit,DataBuffer);
  449.     if (result == 'C')
  450.       CopyToMem(DataBuffer,data,realsize);
  451.       } else result = 'E';
  452.       break;
  453.     case 0x66 : /* US Doubler Format - I think! */
  454.       result = 'A';  /* Not yet supported... to be done later... */
  455.       break;
  456.     default:
  457.       result = 'N';
  458.     }
  459.  
  460.    switch(result) {
  461.    case 0x00:  /* Device disabled, generate timeout */
  462.       regY = 138;
  463.       SetN;
  464.       break;
  465.     case 'A':  /* Device acknoledge */
  466.     case 'C':  /* Operation complete */
  467.       regY = 1;
  468.       ClrN;
  469.       break;
  470.     case 'N': /* Device NAK */
  471.       regY = 144;
  472.       SetN;
  473.       break;
  474.     case 'E': /* Device error */
  475.     default:
  476.       regY = 146;
  477.       SetN;
  478.       break;
  479.     }
  480.  
  481.     Poke(0x0303,regY);
  482.  
  483. #ifdef MOTIF
  484.     Atari_Set_LED(0);
  485. #endif
  486.  
  487. }
  488.  
  489. void SIO_Initialize(void)
  490. {
  491.   TransferStatus = SIO_NoFrame;
  492. }
  493.  
  494.  
  495. UBYTE ChkSum(UBYTE *buffer,UWORD length)
  496. {
  497. int i;
  498. int checksum=0;
  499.  
  500.   for (i=0;i<length;i++,buffer++) {
  501.     checksum += *buffer;
  502.     while (checksum > 255)
  503.       checksum -= 255;
  504.   }
  505.   
  506.   return checksum;
  507. }
  508.    
  509. void Command_Frame (void)
  510. {
  511. int unit;
  512. int result='A';
  513. int sector;
  514. int realsize;
  515.  
  516.  
  517.    sector = CommandFrame[2] | (((UWORD)(CommandFrame[3]))<<8);
  518.    unit = CommandFrame[0]-'1';
  519.    if (unit>8) {   /* UBYTE - range ! */
  520.      printf ("Unknown command frame: %02x %02x %02x %02x %02x\n",
  521.          CommandFrame[0], CommandFrame[1], CommandFrame[2],
  522.          CommandFrame[3], CommandFrame[4]);
  523.      result = 0;
  524.    } else switch (CommandFrame[1]) {
  525.    case 0x4e :  /* Read Status */
  526.       DataBuffer[0] = ReadStatusBlock(unit,DataBuffer+1);
  527.       DataBuffer[13] = ChkSum(DataBuffer+1,12);
  528.       DataIndex = 0;
  529.       ExpectedBytes = 14;
  530.       TransferStatus = SIO_ReadFrame;
  531.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  532.       break;
  533.     case 0x4f :
  534.       ExpectedBytes = 13;
  535.       DataIndex = 0;
  536.       TransferStatus = SIO_WriteFrame;
  537.       break;
  538.     case 0x50 :  /* Write */
  539.     case 0x57 :
  540.       SizeOfSector(unit,sector,&realsize,NULL);
  541.       ExpectedBytes = realsize+1;
  542.       DataIndex = 0;
  543.       TransferStatus = SIO_WriteFrame;
  544.       break;
  545.     case 0x52:   /* Read */     
  546.       SizeOfSector(unit,sector,&realsize,NULL);
  547.       DataBuffer[0] = ReadSector(unit,sector,DataBuffer+1);
  548.       DataBuffer[1+realsize] = ChkSum(DataBuffer+1,realsize);
  549.       DataIndex = 0;
  550.       ExpectedBytes = 2+realsize;
  551.       TransferStatus = SIO_ReadFrame;      
  552.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  553.       break;
  554.     case 0x53:  /* Status */
  555.       DataBuffer[0] = DriveStatus(unit,DataBuffer+1);
  556.       DataBuffer[1+4] = ChkSum(DataBuffer+1,4);
  557.       DataIndex = 0;
  558.       ExpectedBytes = 6;
  559.       TransferStatus = SIO_ReadFrame;
  560.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  561.       break;
  562.     case 0x21 : /* Single Density Format */
  563.       DataBuffer[0] = FormatSingle(unit,DataBuffer+1);
  564.       DataBuffer[1+128] = ChkSum(DataBuffer+1,128);
  565.       DataIndex = 0;
  566.       ExpectedBytes = 2+128;
  567.       TransferStatus = SIO_FormatFrame;
  568.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  569.       break;
  570.     case 0x22 : /* Duel Density Format */     
  571.       DataBuffer[0] = FormatEnhanced(unit,DataBuffer+1);
  572.       DataBuffer[1+128] = ChkSum(DataBuffer+1,128);
  573.       DataIndex = 0;
  574.       ExpectedBytes = 2+128;
  575.       TransferStatus = SIO_FormatFrame;
  576.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  577.       break;
  578.     case 0x66 : /* US Doubler Format - I think! */
  579.       result = 'A';  /* Not yet supported... to be done later... */
  580.       break;
  581.     default :
  582.       printf ("Command frame: %02x %02x %02x %02x %02x\n",
  583.           CommandFrame[0], CommandFrame[1], CommandFrame[2],
  584.           CommandFrame[3], CommandFrame[4]);
  585.       break;
  586.       result = 0;
  587.     }
  588.  
  589.     if (result == 0)
  590.       TransferStatus = SIO_NoFrame;
  591. }
  592.  
  593.  
  594. /* Enable/disable the command frame */
  595. void SwitchCommandFrame(int onoff)
  596. {
  597.  
  598.   if (onoff) {    /* Enabled */
  599.     if (TransferStatus != SIO_NoFrame)
  600.       printf("Unexpected command frame %x.\n",TransferStatus);
  601.     CommandIndex = 0;
  602.     DataIndex = 0;
  603.     ExpectedBytes = 5;
  604.     TransferStatus = SIO_CommandFrame;
  605. #ifdef MOTIF
  606.     Atari_Set_LED(1);
  607. #endif
  608.     /* printf("Command frame expecting.\n"); */
  609.   } else {
  610.     if (TransferStatus!=SIO_StatusRead && TransferStatus!=SIO_NoFrame &&
  611.     TransferStatus!=SIO_ReadFrame) {
  612.       if (!(TransferStatus==SIO_CommandFrame && CommandIndex==0))
  613.     printf("Command frame %02x unfinished.\n",TransferStatus);
  614.       TransferStatus = SIO_NoFrame;
  615.     }
  616.     CommandIndex = 0;
  617.   }
  618. }
  619.  
  620. UBYTE WriteSectorBack(void)
  621. {
  622. UWORD sector;
  623. UBYTE unit;
  624. UBYTE result;
  625.  
  626.    sector = CommandFrame[2] | (((UWORD)(CommandFrame[3]))<<8);
  627.    unit = CommandFrame[0]-'1';
  628.    if (unit>8) {  /* UBYTE range ! */
  629.      result = 0;
  630.    } else switch (CommandFrame[1]) {
  631.    case 0x4f :  /* Write Status Block */
  632.      result=WriteStatusBlock(unit,DataBuffer);
  633.      break;
  634.    case 0x50 :  /* Write */
  635.    case 0x57 :
  636.      result=WriteSector(unit,sector,DataBuffer);
  637.      break;
  638.    default:
  639.      result = 'E';
  640.    }
  641.  
  642.    return result;
  643. }
  644.  
  645. /* Put a byte that comes out of POKEY. So get it here... */
  646. void SIO_PutByte(int byte)
  647. {
  648. UBYTE sum,result;
  649.  
  650.   switch(TransferStatus) {
  651.   case SIO_CommandFrame:
  652.     if (CommandIndex < ExpectedBytes) {
  653.       CommandFrame[CommandIndex++] = byte;
  654.       if (CommandIndex >= ExpectedBytes) {
  655.     /* printf("%x\n",CommandFrame[0]); */
  656.     if (((CommandFrame[0]>=0x31) && (CommandFrame[0]<=0x38))) { 
  657.       TransferStatus = SIO_StatusRead;
  658.       /* printf("Command frame done.\n"); */
  659.       DELAYED_SERIN_IRQ += SERIN_INTERVAL + ACK_INTERVAL;
  660.     } else TransferStatus = SIO_NoFrame;
  661.       } 
  662.     } else {
  663.       printf("Invalid command frame!\n");
  664.       TransferStatus = SIO_NoFrame;
  665.     }
  666.     break;
  667.   case SIO_WriteFrame:  /* Expect data */
  668.     if (DataIndex < ExpectedBytes) {
  669.       DataBuffer[DataIndex++] = byte;
  670.       if (DataIndex >= ExpectedBytes) {
  671.     sum = ChkSum(DataBuffer,ExpectedBytes - 1);
  672.     if (sum == DataBuffer[ExpectedBytes - 1]) {
  673.       result = WriteSectorBack();
  674.       if (result) {
  675.         DataBuffer[0] = 'A';
  676.         DataBuffer[1] = result;
  677.         DataIndex = 0;
  678.         ExpectedBytes = 2;
  679.         DELAYED_SERIN_IRQ += SERIN_INTERVAL + ACK_INTERVAL;
  680.         TransferStatus = SIO_FinalStatus;
  681.         /* printf("Sector written, result= %x.\n",result); */
  682.       } else TransferStatus = SIO_NoFrame;
  683.     } else {
  684.       DataBuffer[0] = 'E';
  685.       DataIndex = 0;
  686.       ExpectedBytes = 1;
  687.       DELAYED_SERIN_IRQ += SERIN_INTERVAL + ACK_INTERVAL;
  688.       TransferStatus = SIO_FinalStatus;
  689.     }
  690.       }
  691.     } else {
  692.       printf("Invalid data frame!\n");
  693.     }
  694.     break;
  695.   default:
  696.     printf("Unexpected data output :%x\n",byte);
  697.   }
  698.   DELAYED_SEROUT_IRQ += SEROUT_INTERVAL;
  699.  
  700. }
  701.  
  702. /* Get a byte from the floppy to the pokey. */
  703.  
  704. int SIO_GetByte(void)
  705. {
  706. int byte = 0;
  707.  
  708.   switch(TransferStatus) {
  709.   case SIO_StatusRead:
  710.     byte = 'A';   /* Command acknoledged */
  711.     /* printf("Command status read\n"); */
  712.     Command_Frame();  /* Handle now the command */      
  713.     break;
  714.   case SIO_FormatFrame:
  715.     TransferStatus = SIO_ReadFrame;
  716.     DELAYED_SERIN_IRQ += SERIN_INTERVAL<<3;
  717.   case SIO_ReadFrame:
  718.     if (DataIndex < ExpectedBytes) {
  719.       byte=DataBuffer[DataIndex++];
  720.       if (DataIndex >= ExpectedBytes) {
  721.     TransferStatus = SIO_NoFrame;
  722. #ifdef MOTIF
  723.     Atari_Set_LED(0);
  724. #endif
  725.     /* printf("Transfer complete.\n"); */
  726.       } else {
  727.       DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  728.       }
  729.     } else {
  730.       printf("Invalid read frame!\n");
  731.       TransferStatus = SIO_NoFrame;
  732.     }
  733.     break;
  734.   case SIO_FinalStatus:  
  735.     if (DataIndex < ExpectedBytes) {
  736.       byte=DataBuffer[DataIndex++];
  737.       if (DataIndex >= ExpectedBytes) {
  738.     TransferStatus = SIO_NoFrame;
  739. #ifndef BASIC
  740.     Atari_Set_LED(0);
  741. #endif
  742.     /* printf("Write complete.\n"); */
  743.       } else {
  744.     if (DataIndex == 0)
  745.       DELAYED_SERIN_IRQ += SERIN_INTERVAL+ACK_INTERVAL;
  746.     else DELAYED_SERIN_IRQ += SERIN_INTERVAL;
  747.       }
  748.     } else {
  749.       printf("Invalid read frame!\n");
  750. #ifndef BASIC
  751.     Atari_Set_LED(0);
  752. #endif
  753.       TransferStatus = SIO_NoFrame;
  754.     }
  755.     break;
  756.   default:
  757.     printf("Unexpected data reading!\n");
  758.     break;
  759.   }
  760.   
  761.   return byte;
  762. }
  763.